package com.khstudio.filebrowser.bitmapcache;

import java.util.LinkedList;

import com.khstudio.filebrowser.util.KhLog;

import android.content.Context;
import android.graphics.Bitmap;

public abstract class KhBitmapCache {
    private static final int THREAD_STATE_READY         = 0x0000;
    private static final int THREAD_STATE_RUNNING       = 0x0001;

    private KhBitmapLruCache                  mDiskCache;
    private KhBitmapLruCache                  mMemoryCache;

    private Task                              mTask;
    private int                               mTaskState;

    private LinkedList<KhBitmapCacheParam<?>> mList;

    public abstract Bitmap onLoadBitmap(String filename);
    public abstract void   onLoadDone(KhBitmapCacheParam<?> param);

    public KhBitmapCache(Context context, String uniqueName, int memoryCacheSize, int diskCacheSize) {
        mDiskCache   = new KhBitmapLruCacheDisk(context, uniqueName, diskCacheSize);
        mMemoryCache = new KhBitmapLruCacheMemory(memoryCacheSize);

        mList = new LinkedList<KhBitmapCacheParam<?>>();

        mTaskState = THREAD_STATE_READY;
    }

    public void stop() {
        if(mTaskState == THREAD_STATE_RUNNING) {
            mTask.stopThread();
            mTaskState = THREAD_STATE_READY;
        }
    }

    public Bitmap load(KhBitmapCacheParam<?> param) {
        String key = param.getKey();
        Bitmap bm  = mMemoryCache.get(key);

        if(bm == null) {
            synchronized (mList) {
                boolean skip = false;

                for(KhBitmapCacheParam<?> item : mList) {
                    if(item.getKey().compareTo(key) == 0) {
                        skip = true;
                        break;
                    }
                }

                if(!skip) {
                    mList.add(param);
                }
            }

            if(mTaskState == THREAD_STATE_READY) {
                mTaskState = THREAD_STATE_RUNNING;
                mTask = new Task();
                mTask.start();
            }
        } else {
            KhLog.d("load get MemoryCache key = "+key);
        }

        return bm;
    }

    private class Task extends Thread {
        public boolean running;

        public void stopThread() {
            running = false;
        }

        @Override
        public void run() {
            running = true;

            KhBitmapCacheParam<?> item = null;
            Bitmap bm = null;

            while(running) {
                synchronized (mList) {
                    if(mList.size() > 0) {
                        item = mList.remove();
                    } else {
                        running = false;
                        mTaskState = THREAD_STATE_READY;
                        break;
                    }
                }

                String key = item.getKey();
                bm = mDiskCache.get(key);

                if(bm == null) {
                    bm = onLoadBitmap(item.getPath());
                    if(bm != null)
                        mDiskCache.put(key, bm);
                } else {
                    KhLog.d("load get DiskCache key = "+key);
                }

                if(bm != null) {
                    mMemoryCache.put(key, bm);
                    item.setBitmap(bm);
                }
                onLoadDone(item);
            }
        }
    }
}
